package com.easy.dfc.web;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.aliyuncs.vod.model.v20170321.*;
import com.easy.core.web.BaseController;
import com.easy.dfc.Utils.Error;
import com.easy.dfc.Utils.JsonUtil;
import com.easy.dfc.Utils.Util;
import com.easy.dfc.entity.Video;
import com.easy.dfc.service.UsersetService;
import com.easy.dfc.service.VideoService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;

@Controller
@RequestMapping("${apiPath}/Video")
public class VideoController extends BaseController {

    @Resource
    private UsersetService usersetService;

    @Resource
    private VideoService videoService;

    // 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
    public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
    // 当前 STS API 版本
    public static final String STS_API_VERSION = "2015-04-01";
    /**
     * * 获取上传地址和上传凭证
     *
     * @param request
     * @return0
     */
    @RequestMapping(value = "/createUploadVideo", method = RequestMethod.POST)
    public ResponseEntity<JSONObject> createUploadVideo(HttpServletRequest request) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpSession session = request.getSession();
        JSONObject jsonObject = new JSONObject();
        try {
            String userId = request.getParameter("UserId");
            String token = request.getParameter("Token");
            if (!usersetService.VerifyToken(userId, token)) {
                jsonObject.put("Err", Error.ValidFailed);
                return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
            }
            String fileName = request.getParameter("FileName");
            long size = Long.parseLong(request.getParameter("Size"));
            String title = request.getParameter("Title");
            DefaultAcsClient aliyunClient;
            aliyunClient = new DefaultAcsClient(
                    DefaultProfile.getProfile("cn-shanghai", Util.accessKeyId, Util.accessKeySecret));
            CreateUploadVideoRequest videorequest = new CreateUploadVideoRequest();
            CreateUploadVideoResponse response = null;
            /*必选，视频源文件名称（必须带后缀, 支持 "3GP","AVI","FLV","MP4","M3U8","MPG","ASF","WMV","MKV","MOV","TS",    "WebM","MPEG","RM","RMVB","DAT","ASX","WVX","MPE","MPA","F4V","MTS","VOB","GIF"）*/
            videorequest.setFileName(fileName);
            //必选，视频源文件字节数
            videorequest.setFileSize(size);
            //必选，视频标题
            videorequest.setTitle(title);
            //可选，分类ID
//                videorequest.setCateId(0);
            //可选，视频标签，多个用逗号分隔
//                videorequest.setTags("标签1,标签2");
            //可选，视频描述
//                videorequest.setDescription("视频描述");1939358727
            //可选，视频上传所在区域IP
            videorequest.setIP(Util.getIpAddress(request));
            response = aliyunClient.getAcsResponse(videorequest);
            jsonObject.put("VideoId", response.getVideoId());
            jsonObject.put("UploadAuth", response.getUploadAuth());
            jsonObject.put("UploadAddress", response.getUploadAddress());
            JSONObject j = JSONObject.parseObject(Util.getFromBase64(response.getUploadAddress()));
            jsonObject.put("Endpoint", j.get("Endpoint"));
            jsonObject.put("Bucket", j.get("Bucket"));
            jsonObject.put("FileName", j.get("FileName"));
            jsonObject = JSONObject.parseObject(JsonUtil.toErrJson(Error.OK, jsonObject.toJSONString()));
        } catch (Exception e) {
            jsonObject.put("Err", Error.OtherError);
            return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
        }
        return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
    }

    /**
     * * 刷新上传凭证
     *
     * @param request
     * @return0
     */
    @RequestMapping(value = "/refreshUploadVideo", method = RequestMethod.POST)
    public ResponseEntity<JSONObject> refreshUploadVideo(HttpServletRequest request) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpSession session = request.getSession();
        JSONObject jsonObject = new JSONObject();
        try {
            String userId = request.getParameter("UserId");
            String token = request.getParameter("Token");
            if (!usersetService.VerifyToken(userId, token)) {
                jsonObject.put("Err", Error.ValidFailed);
                return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
            }
            String videoId = request.getParameter("VideoId");
            DefaultAcsClient aliyunClient;
            aliyunClient = new DefaultAcsClient(
                    DefaultProfile.getProfile("cn-shanghai", Util.accessKeyId, Util.accessKeySecret));
            RefreshUploadVideoRequest videorequest = new RefreshUploadVideoRequest();
            RefreshUploadVideoResponse response = null;
            videorequest.setVideoId(videoId);
            response = aliyunClient.getAcsResponse(videorequest);
            System.out.println("RequestId:" + response.getRequestId());
            System.out.println("UploadAuth:" + response.getUploadAuth());
            jsonObject.put("UploadAuth", response.getUploadAuth());
            jsonObject = JSONObject.parseObject(JsonUtil.toErrJson(Error.OK, jsonObject.toJSONString()));
        } catch (Exception e) {
            jsonObject.put("Err", Error.OtherError);
            return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
        }
        return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
    }

    /**
     * * 转码成功回调
     *
     * @param request
     * @return0
     */
    @RequestMapping(value = "/StreamTranscodeComplete", method = RequestMethod.POST)
    @Transactional
    public ResponseEntity<JSONObject> StreamTranscodeComplete(HttpServletRequest request) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpSession session = request.getSession();
        JSONObject jsonObject = new JSONObject();
        try {
            String line = null;
            StringBuffer json = new StringBuffer();
            BufferedReader reader = request.getReader();
            while ((line = reader.readLine()) != null) {
                json.append(line);
            }
            reader.close();
            JSONObject jsonObject1 = JSONObject.parseObject(json.toString());
            Video video = new Video();
            String EventType = jsonObject1.getString("EventType");
            if ("StreamTranscodeComplete".equals(EventType)) {
                String Status = jsonObject1.getString("Status");
                video.setStatus(Status);
                if ("success".equals(Status)) {
                    video.setBitrate(Float.parseFloat(jsonObject1.getString("Bitrate")));
                    video.setDefinition(jsonObject1.getString("Definition"));
                    video.setDuration(Float.parseFloat(jsonObject1.getString("Duration")));
                    video.setEncrypt(jsonObject1.getString("Encrypt"));
                    video.setEventtime(jsonObject1.getString("EventTime"));
                    video.setEventtype(jsonObject1.getString("EventType"));
                    video.setFileurl(jsonObject1.getString("FileUrl"));
                    video.setFormat(jsonObject1.getString("Format"));
                    video.setFps(Float.parseFloat(jsonObject1.getString("Fps")));
                    video.setHeight(Long.parseLong(jsonObject1.getString("Height")));
                    video.setWidth(Long.parseLong(jsonObject1.getString("Width")));
                    video.setSize(Long.parseLong(jsonObject1.getString("Size")));
                    video.setVideoid(jsonObject1.getString("VideoId"));
                } else {
                    video.setErrorcode(jsonObject1.getString("ErrorCode"));
                    video.setErrormessage(jsonObject1.getString("ErrorMessage"));
                }
                videoService.insertSelective(video);
            }
            jsonObject.put("Err", Error.OK);
        } catch (Exception e) {
            jsonObject.put("Err", Error.OtherError);
            return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
        }
        return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
    }

    /**
     * * 获取播放凭证
     *
     * @param request
     * @return0
     */
    @RequestMapping(value = "/getVideoPlayAuth", method = RequestMethod.POST)
    public ResponseEntity<JSONObject> getVideoPlayAuth(HttpServletRequest request) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpSession session = request.getSession();
        JSONObject jsonObject = new JSONObject();
        try {
            String userId = request.getParameter("UserId");
            String token = request.getParameter("Token");
            if (!usersetService.VerifyToken(userId, token)) {
                jsonObject.put("Err", com.easy.dfc.Utils.Error.ValidFailed);
                return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
            }
            String VideoId = request.getParameter("VideoId");
            DefaultAcsClient aliyunClient;
            aliyunClient = new DefaultAcsClient(
                    DefaultProfile.getProfile("cn-shanghai", Util.accessKeyId, Util.accessKeySecret));
            GetVideoPlayAuthRequest playAutrequest = new GetVideoPlayAuthRequest();
            playAutrequest.setVideoId(VideoId);
            GetVideoPlayAuthResponse response = null;
            response = aliyunClient.getAcsResponse(playAutrequest);
            jsonObject.put("PlayAuth", response.getPlayAuth());//播放凭证
            jsonObject.put("VideoMeta", response.getVideoMeta());//视频Meta信息
            jsonObject = JSONObject.parseObject(JsonUtil.toErrJson(Error.OK, jsonObject.toJSONString()));
        } catch (Exception e) {
            jsonObject.put("Err", Error.OtherError);
            return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
        }
        return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
    }
    /**
     * * 获取播放凭证
     *
     * @param request
     * @return0
     */
    @RequestMapping(value = "/getVideoPlay", method = RequestMethod.POST)
    public ResponseEntity<JSONObject> getVideoPlay(HttpServletRequest request) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON);
        HttpSession session = request.getSession();
        JSONObject jsonObject = new JSONObject();
        try {
            String userId = request.getParameter("UserId");
            String token = request.getParameter("Token");
            if (!usersetService.VerifyToken(userId, token)) {
                jsonObject.put("Err", com.easy.dfc.Utils.Error.ValidFailed);
                return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
            }
            String VideoId = request.getParameter("VideoId");
            // 只有 RAM用户（子账号）才能调用 AssumeRole 接口
            // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
            // 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
            //String accessKeyId = Util.accessKeyId;
            //String accessKeySecret = Util.accessKeySecret;

            String accessKeyId = "LTAI6rRL1udC8TkO";
            String accessKeySecret = "mEbXTwz7fWh6OWPtd3BYsfldJ9DtMs";


            // AssumeRole API 请求参数: RoleArn, RoleSessionName, Policy, and DurationSeconds
            // RoleArn 需要在 RAM 控制台上获取
            String roleArn = "acs:ram::1215374545979143:role/ossadmin";

            // RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
            // 但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符
            // 具体规则请参考API文档中的格式要求
            String roleSessionName = "alice-001";
            // 如何定制你的policy?
            String policy = "{\n" +
                    "    \"Version\": \"1\", \n" +
                    "    \"Statement\": [\n" +
                    "        {\n" +
                    "            \"Action\": [\n" +
                    "                \"oss:GetBucket\", \n" +
                    "                \"oss:GetObject\" \n" +
                    "            ], \n" +
                    "            \"Resource\": [\n" +
                    "                \"acs:oss:*:*:*\"\n" +
                    "            ], \n" +
                    "            \"Effect\": \"Allow\"\n" +
                    "        }\n" +
                    "    ]\n" +
                    "}";
            // 此处必须为 HTTPS
            ProtocolType protocolType = ProtocolType.HTTPS;
            try {
                final AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret,
                        roleArn, roleSessionName, policy, protocolType);

                jsonObject.put("Expiration", response.getCredentials().getExpiration());//播放凭证
                jsonObject.put("accessKeyId", response.getCredentials().getAccessKeyId());//播放凭证
                jsonObject.put("accessKeySecret", response.getCredentials().getAccessKeySecret());//播放凭证
                jsonObject.put("securityToken", response.getCredentials().getSecurityToken());//播放凭证

            } catch (ClientException e) {
                System.out.println("Failed to get a token.");
                jsonObject.put("Err", e.getErrCode());
                jsonObject.put("ErrMsg", e.getErrMsg());
                jsonObject.put("E", e.toString());
            }

            jsonObject = JSONObject.parseObject(JsonUtil.toErrJson(Error.OK, jsonObject.toJSONString()));
        } catch (Exception e) {
            jsonObject.put("Err", Error.OtherError);
            return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
        }
        return new ResponseEntity<JSONObject>(jsonObject, responseHeaders, HttpStatus.OK);
    }
    private AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret,
                                          String roleArn, String roleSessionName, String policy,
                                          ProtocolType protocolType) throws ClientException {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion(STS_API_VERSION);
            request.setMethod(MethodType.POST);
            request.setProtocol(protocolType);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            // 发起请求，并得到response
            final AssumeRoleResponse response = client.getAcsResponse(request);
            return response;
        } catch (ClientException e) {
            throw e;
        }
    }
}
